package com.yanqu.road.server.manager.activity.suitang.manager;

import com.yanqu.road.entity.activity.suitang.config.SuiTangConfigSync;
import com.yanqu.road.entity.activity.suitang.data.CrossSuiTangUserData;
import com.yanqu.road.entity.activity.suitang.entity.barracks.CrossSuiTangBarracks;
import com.yanqu.road.entity.activity.suitang.entity.battle.CrossSuiTangBattlefieldTeam;
import com.yanqu.road.entity.activity.suitang.data.CrossSuiTangCity;
import com.yanqu.road.entity.activity.suitang.entity.team.CrossSuiTangTeam;
import com.yanqu.road.entity.activity.suitang.entity.team.CrossSuiTangTeamArrive;
import com.yanqu.road.entity.activity.suitang.entity.union.CrossSuiTangUnionRound;
import com.yanqu.road.entity.activity.suitang.entity.user.CrossSuiTangUserRound;
import com.yanqu.road.entity.activity.suitang.enums.eSuiTangBuffType;
import com.yanqu.road.entity.activity.suitang.enums.eSuiTangStage;
import com.yanqu.road.entity.activity.suitang.enums.eSuiTangTeamStatus;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.server.manager.activity.ActivityMgr;
import com.yanqu.road.server.manager.activity.suitang.task.impl.CrossSuiTangAutoBattleTask;
import com.yanqu.road.server.manager.activity.suitang.task.impl.CrossSuiTangBarracksRecoveryTask;
import com.yanqu.road.server.manager.config.GoodsMgr;
import com.yanqu.road.server.manager.user.CrossUserMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.date.DateHelper;

import java.math.BigDecimal;
import java.util.Map;

public class CrossSuiTangBarracksActivityMgr extends CrossBaseActivityMgr {

    @Override
    public void init() {
        resetBarracks();
        for (CrossSuiTangUserData userData : activity.getUserDataMap().values()) {
            refreshTeam(userData);
        }
    }

    /*
     * 调整兵力
     */
    public int changeSoldier(long userId, long soldierNum) {
        if (!activity.isAble(userId)) {
            return GameErrorCode.E_SUI_TANG_NO_ABLE;
        }
        if (activity == null) {
            return GameErrorCode.E_SUI_TANG_ACTIVITY_NOT_FOUND;
        }
        SuiTangConfigSync config = activity.getConfig();
        if (config == null) {
            return GameErrorCode.E_SUI_TANG_CONFIG_NOT_FOUND;
        }
        if (!ActivityMgr.activityInTime(config.getActivityInfo())) {
            return GameErrorCode.E_SUI_TANG_NO_OPERATE_TIME;
        }
        if (!activity.isBattleStep()) {
            return GameErrorCode.E_SUI_TANG_NO_OPERATE_TIME;
        }
        CrossSuiTangUserData userData = activity.getUserData(userId);
        if (userData == null) {
            return GameErrorCode.E_SUI_TANG_PARAM_ERR;
        }
        if (!isHomeCity(getCity(userId), activity.getUserData(userId).getUnionUid())) {
            return GameErrorCode.E_SUI_TANG_NOT_IN_HOME;
        }

        synchronized (getPlayerLock(userId)) {
            // 自动补兵和玩家手动补兵并发
            barracksCalc(userId);

            CrossSuiTangTeam team = userData.getTeam();
            CrossSuiTangBarracks barracks = userData.getBarracks();
            if (barracks == null || team == null || soldierNum < team.getSoldierNum()) {
                return GameErrorCode.E_SUI_TANG_PARAM_ERR;
            }
            if (getTeamStatus(team).getValue() != eSuiTangTeamStatus.Free.getValue()) {
                return GameErrorCode.E_SUI_TANG_TEAM_CHANGE_SOLDIER_NO_FREE;
            }
            if (team.getMaxSoldier() < soldierNum || soldierNum < 0) {
                return GameErrorCode.E_SUI_TANG_TEAM_CHANGE_SOLDIER_MAX;
            }
            if (team.getCurBattleNum() > 0 && activity.getMapActivityMgr().soldierLimit(team)) {
                return GameErrorCode.E_SUI_TANG_PI_BI;
            }
            if (userData.getBarracks().getReadyNum() < soldierNum - team.getSoldierNum()) {
                return GameErrorCode.E_SUI_TANG_TEAM_CHANGE_SOLDIER_NO_ENOUGH;
            }
            long oldSoldierNum = team.getSoldierNum();
            team.setSoldierNum(soldierNum);
            barracks.setReadyNum(barracks.getReadyNum() - (soldierNum - oldSoldierNum));
            team.setWinTimes(0);
            team.setWinTime(System.currentTimeMillis());
            userData.setUpdateOption();
            activity.getLogActivityMgr().addBarracksLog(userId, (soldierNum - oldSoldierNum), 2);
        }

        if (activity.getMapActivityMgr().soldierLimit(userData.getTeam())) {
            // 兵力足够，加入对应队列
            CrossSuiTangUnionRound unionData = getUnionRoundData(userData.getUnionUid());
            CrossSuiTangCity homeCity = getCurCity(userData.getUserId(), unionData.getHomeId());
            if (homeCity != null) {
                synchronized (getCityLock(homeCity)) {
                    if (!isOut(userData.getUserId())) {
                        homeCity.getBattlefield().getDefTeamMap().put(userData.getUserId(), new CrossSuiTangBattlefieldTeam(new CrossSuiTangTeamArrive(userData.getUserId(), System.currentTimeMillis())));
                    }
                }
                activity.getSyncActivityMgr().syncCity(homeCity, false);
                if (userData.getTeam().isAutoBattle()
                        && (userData.getTeam().getTargetCityId() == 0)) {
                    // 补完兵之后：开着自动战斗且没有目标城市，原地战斗，可能别人在攻打自己的大本营
                    // 有自动行军目标的，则有行军那边处理是否自动战斗
                    //activity.addTask(new CrossSuiTangAutoBattleTask(activity, System.currentTimeMillis(), getCity(userId), getBattleTeam(homeCity, userId)));
                    //activity.getBattleActivityMgr().autoAttack(homeCity, getBattleTeam(homeCity, userId));
                }
            }
        }

        // 在家里，补完兵同步下队列
        activity.getSyncActivityMgr().syncBattleResultMsg(getCity(userId));

        return 0;
    }

    /*
     * 同步玩家兵力相关数据
     */
    public int syncPatrons(long userId, boolean isFirst, long patronsTotalAbility, long addition, long patronsNSum, int patronsTotalNum, boolean isRefreshMaxSoldier) {
        int ret = 0;
        CrossSuiTangUserData userData = activity.getUserData(userId);
        if (!isRefreshMaxSoldier) {
            if (!isFirst && System.currentTimeMillis() - userData.getLastSyncPatronsTime() < activity.getConfig().getParamConfig().getSuiTangPowerCoolDownTime() * DateHelper.SECOND_MILLIONS) {
                return GameErrorCode.E_SUI_TANG_REQ_FREQUENTLY;
            }
            if (activity.getBattleActivityMgr().getTeamStatus(userData.getTeam()) != eSuiTangTeamStatus.Free) {
                return GameErrorCode.E_SUI_TANG_TEAM_NO_FREE;
            }
            if (!isFirst && !isHomeCity(getCity(userId), activity.getUserData(userId).getUnionUid())) {
                return GameErrorCode.E_SUI_TANG_NOT_IN_HOME;
            }
        }

        updateUserSoldierParam(userData, patronsTotalAbility, addition, patronsNSum, patronsTotalNum);
        refreshTeam(userData);

        if (!isRefreshMaxSoldier) {
            // 表示玩家手动同步，需要把兵力返回到预备兵营
            userData.getBarracks().setReadyNum(userData.getBarracks().getReadyNum() + userData.getTeam().getSoldierNum());
            userData.getTeam().setSoldierNum(0);

            if (isFirst) {
                userData.getTeam().setSoldierNum(userData.getTeam().getMaxSoldier());
                handleNextRound(userData);
            } else {
                userData.setLastSyncPatronsTime(System.currentTimeMillis());
                // 还要从队列中移除
                CrossSuiTangCity city = getCity(userData.getUserId());
                synchronized (getCityLock(city)) {
                    if (city != null) {
                        city.getBattlefield().getDefTeamMap().remove(userData.getUserId());
                    }
                }
                activity.getSyncActivityMgr().syncCity(city, false);
            }
        }
        userData.setUpdateOption();
        activity.getSyncActivityMgr().syncBaseDataMsg(userData.getUserId());
        activity.getSyncActivityMgr().syncTeamToSelf(userData.getTeam());

        return ret;
    }

    /*
     * 处理跨轮次进战场时，兵营的计算
     */
    public void handleNextRound(CrossSuiTangUserData userData) {
        if (calcRound() > 1) {
            long createTime = activity.getConfig().getStage1TimeList().get(0).get(1) - activity.getConfig().getStage1TimeList().get(0).get(0);
            long createNum = createTime / DateHelper.MINUTE_MILLIONS * (calcRound() - 1) * userData.getBarracks().getCreateSpeed();
            if (createNum > userData.getBarracks().getReadyMaxNum()) {
                createNum = userData.getBarracks().getReadyMaxNum();
            }
            userData.getBarracks().setReadyNum(createNum);
        }
    }

    /*
     * 更新玩家兵力数据
     */
    public void updateUserSoldierParam(CrossSuiTangUserData userData, long patronsTotalAbility, long addition, long patronsNSum, int patronsTotalNum) {
        synchronized (getPlayerLock(userData.getUserId())) {
            userData.setSoldierAddition(addition);
            userData.setPatronsTotalAbility(patronsTotalAbility);
            userData.setPatronsNSum(patronsNSum);
            userData.setPatronsTotalNum(patronsTotalNum);
            //userData.setLastSyncPatronsTime(System.currentTimeMillis());
            userData.setUpdateOption();
        }
    }

    /*
     * 重置兵营模块
     */
    public void resetBarracks() {
        calcAllBarracks();

        for (CrossSuiTangUserData userData : activity.getUserDataMap().values()) {
            CrossSuiTangTeam team = userData.getTeam();
            if (team != null) {
                team.setCityId(0);
                team.setFromCityId(0);
                team.setTargetCityId(0);
                team.setBeginMoveTime(0);
                team.setMoveUpdateTime(System.currentTimeMillis());
                team.setSoldierNum(team.getMaxSoldier());
                team.setCurBattleNum(0);
                team.setWinTime(0);
                team.setWinTimes(0);
                CrossSuiTangBarracks barracks = userData.getBarracks();
                barracks.setCreateTime(activity.getConfig().getRoundBeginTime(calcRound()));
            }
            refreshTeam(userData);
        }
    }

    /*
     * 刷新队伍
     */
    public void refreshTeam(CrossSuiTangUserData userData) {
        CrossSuiTangTeam team = userData.getTeam();
        team.setMaxSoldier(calcTeamMaxSoldier(userData, team));
//        team.setSoldierNum(team.getMaxSoldier());
        team.setUserId(userData.getUserId());
        CrossSuiTangUserRound curUserRound = getCurUserRound(userData.getUserId());
        if (curUserRound != null) {
            team.setFromCityId(curUserRound.getCityId());
            team.setCityId(team.getCityId() == 0 ? curUserRound.getCityId() : team.getCityId());
        }
        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userData.getUserId());
        if (userBaseInfo != null) {
            team.setNickname(userBaseInfo.getNickName());
        }
        recalculateBarracksReadyMaxNum(userData.getUserId());
        userData.setUpdateOption();
    }

    /*
     * 尝试刷新队伍
     */
    public void tryRefreshTeam(CrossSuiTangUserData userData) {
        if (userData.getTeam().getCityId() == 0) {
            refreshTeam(userData);
        }
    }

    /*
     * 自动征兵
     */
    public void barracksRecoveryTask() {
        calcAllBarracks();
        //activity.addTask(new CrossSuiTangBarracksRecoveryTask(activity, System.currentTimeMillis() + DateHelper.MINUTE_MILLIONS));
    }

    /**
     * 计算全部兵营
     */
    public void calcAllBarracks() {
        if (activity == null) {
            return;
        }
        Map<Long, CrossSuiTangUserData> userDataMap = activity.getUserDataMap();
        if (userDataMap == null || userDataMap.isEmpty()) {
            return;
        }
        for (CrossSuiTangUserData userData : userDataMap.values()) {
            CrossSuiTangBarracks barracks = userData.getBarracks();
            if (activity.isAble(userData.getUserId()) && barracks.getReadyMaxNum() > 0) {
                barracksCalc(userData.getUserId());
            }
        }
    }

    /**
     * 计算兵营的产出
     */
    public void barracksCalc(long userId) {
        if (activity == null) {
            return;
        }
        SuiTangConfigSync config = activity.getConfig();
        if (config == null) {
            return;
        }

        synchronized (getPlayerLock(userId)) {
            // 手动补兵和自动补兵，都会计算兵力，存在并发
            CrossSuiTangUserData userData = activity.getUserData(userId);
            CrossSuiTangBarracks barracks = userData.getBarracks();

            // 部分数据未完成，这边先不处理
            if (barracks.getReadyMaxNum() <= 0 || userData.getUserBaseInfo().getTitleId() == 0) {
                return;
            }

            long nowTime = Math.min(System.currentTimeMillis(), DateHelper.getZeroTimeStamp(barracks.getCreateTime()) + 22 * DateHelper.HOUR_MILLIONS);

            if (barracks.getReadyNum() >= barracks.getReadyMaxNum()) {
                barracks.setCreateTime(nowTime);
                return;
            }
            if (nowTime <= barracks.getCreateTime()) {
                return;
            }

            // 计算征兵速度
            int baseSpeed = config.getParamConfig().getSuiTangSoldierRecoverCond(userData.getUserBaseInfo().getTitleId());
            // 名城buff 待定
            barracks.setCreateSpeed(baseSpeed);

            long createTime = barracks.getCreateTime();
            // 征兵了几分钟
            long min = (nowTime - createTime) / DateHelper.MINUTE_MILLIONS;
            // 征兵了几个
            long createNumber = min * barracks.getCreateSpeed();
            // 可以全部征完
            if (createNumber >= barracks.getReadyMaxNum() - barracks.getReadyNum()) {
                createNumber = barracks.getReadyMaxNum() - barracks.getReadyNum();
            }

            barracks.setCreateTime(barracks.getCreateTime() + min * DateHelper.MINUTE_MILLIONS);
            barracks.setReadyNum(barracks.getReadyNum() + createNumber);
            userData.setUpdateOption();
        }
    }

    /**
     * 重新计算最大兵营数，来触发时候要有buff，开始和失效时候触发 Type6_ReadySoldierMaxNum
     */
    public void recalculateBarracksReadyMaxNum(long userId) {
        if (activity == null) {
            return;
        }
        SuiTangConfigSync config = activity.getConfig();
        if (config == null) {
            return;
        }
        synchronized (getPlayerLock(userId)) {
            // 定时刷新buff和玩家手动同步战力存在并发
            CrossSuiTangUserData userData = activity.getUserData(userId);
            CrossSuiTangBarracks barracks = userData.getBarracks();
            barracks.setReadyMaxNum(calcBarracksReadyMaxNum(userId));
            int baseSpeed = config.getParamConfig().getSuiTangSoldierRecoverCond(userData.getUserBaseInfo().getTitleId());
            barracks.setCreateSpeed(baseSpeed);
            userData.setUpdateOption();
        }
    }

    /**
     * 计算军营预备兵上限
     */
    private long calcBarracksReadyMaxNum(long userId) {
        if (activity == null) {
            return 0L;
        }
        SuiTangConfigSync config = activity.getConfig();
        if (config == null) {
            return 0L;
        }
        // 拿队伍带兵上限总和
        CrossSuiTangUserData userData = activity.getUserData(userId);
        long allValue = userData.getTeam().getMaxSoldier();

        // 乘以参数
        allValue = allValue * config.getParamConfig().getSuiTangBarrackNumLimitParam() / 1000;
        // 加buff
        Map<Integer, CrossSuiTangUserRound> userRoundMap = userData.getUserRoundMap();
        if (userRoundMap == null || userRoundMap.isEmpty()) {
            return 0;
        }
        Integer buffAddition = getBuffAddition(userData.getUnionUid(), eSuiTangBuffType.Type7_ReadySoldierMaxNum);
        allValue = BigDecimal.valueOf(allValue)
                .multiply(BigDecimal.valueOf(1000 + buffAddition)).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_DOWN).longValue();
        return allValue;
    }

    /**
     * 计算队伍兵力上限
     */
    public long calcTeamMaxSoldier(CrossSuiTangUserData userData, CrossSuiTangTeam team) {
        if (activity == null) {
            return 0;
        }
        if (activity.getNpcTestActivityMgr().isNpc(userData.getUserId())) {
            return randomHelper.next(5000, 99999);
        }
        SuiTangConfigSync config = activity.getConfig();
        if (config == null) {
            return 0;
        }
        // 每个职业前 N 门客总赚钱（上传时计算好的）
        long totalAbility = userData.getPatronsTotalAbility();
        if (totalAbility <= 0) {
            return 0;
        }
        long patronsNSum = userData.getPatronsNSum();
        if (patronsNSum <= 0) {
            return 0;
        }
        int otherPatronsCount = (int) (userData.getPatronsTotalNum() - patronsNSum);
        if (otherPatronsCount < 0) {
            otherPatronsCount = 0;
        }

        // 计算
        BigDecimal paramAbility = BigDecimal.valueOf(totalAbility);
        BigDecimal paramHouQinCount = BigDecimal.valueOf(otherPatronsCount);
        BigDecimal param1 = BigDecimal.valueOf(config.getParamConfig().getSuiTangTeamNumLimitParam().get(0));
        BigDecimal param2 = BigDecimal.valueOf(config.getParamConfig().getSuiTangTeamNumLimitParam().get(1));
        BigDecimal param3 = BigDecimal.valueOf(config.getParamConfig().getSuiTangTeamNumLimitParam().get(2));
        BigDecimal param4 = BigDecimal.valueOf(config.getParamConfig().getSuiTangTeamNumLimitParam().get(3));
        BigDecimal param5 = BigDecimal.valueOf(config.getParamConfig().getSuiTangTeamNumLimitParam().get(4));
        BigDecimal one = BigDecimal.ONE;

        // log x param2
        BigDecimal logPart = BigDecimal.valueOf(
                Math.log10(paramAbility.divide(param1, 8, BigDecimal.ROUND_DOWN).doubleValue())
        ).multiply(param2).setScale(8, BigDecimal.ROUND_DOWN);

        // 1 + 后勤 x 参数3/4
        BigDecimal houQinPart = one.add(
                paramHouQinCount.multiply(
                        param3.divide(param4, 8, BigDecimal.ROUND_DOWN)
                )
        );

        // 左边一大串
        BigDecimal leftPart = logPart.multiply(houQinPart);

        // max
        if (leftPart.compareTo(param5) < 0) {
            leftPart = param5;
        }

        // buff 加成
//        Map<Integer, CrossSuiTangUserRound> userRoundMap = userData.getUserRoundMap();
//        if (userRoundMap == null || userRoundMap.isEmpty()) {
//            return 0;
//        }
        int buffAddition = /*getBuffAddition(
                userRoundMap.get(calcRound()).getWarType(),
                userRoundMap.get(calcRound()).getActGroupId(),
                userData.getUnionUid(),
                eSuiTangBuffType.Type1_TeamSoldierMaxNum)*/ 0;

        // 天赋加成
        long patronsAddition = userData.getSoldierAddition();

        // 总
        leftPart = leftPart.add(BigDecimal.valueOf(patronsAddition)).add(BigDecimal.valueOf(buffAddition));

        return leftPart.setScale(0, BigDecimal.ROUND_DOWN).longValue();
    }

    /**
     * 使用募兵令
     */
    public int useMuBingLing(long userId, int goodsId, long count) {
        if (!activity.isAble(userId)) {
            return GameErrorCode.E_SUI_TANG_NO_ABLE;
        }
        if (activity == null) {
            return GameErrorCode.E_SUI_TANG_ACTIVITY_NOT_FOUND;
        }
        SuiTangConfigSync config = activity.getConfig();
        if (config == null) {
            return GameErrorCode.E_SUI_TANG_CONFIG_NOT_FOUND;
        }
        if (!ActivityMgr.activityInTime(config.getActivityInfo()) && !config.inReadyTime()) {
            return GameErrorCode.E_SUI_TANG_NO_OPERATE_TIME;
        }

        barracksCalc(userId);

        CrossSuiTangUserData userData = activity.getUserData(userId);
        if (userData == null) {
            return GameErrorCode.E_SUI_TANG_NO_ABLE;
        }

        CrossSuiTangBarracks barracks = userData.getBarracks();
        if (barracks == null) {
            return GameErrorCode.E_SUI_TANG_PARAM_ERR;
        }
        GoodsInfo goodsInfo = GoodsMgr.getGoodsInfo(goodsId);
        if (goodsInfo == null) {
            return GameErrorCode.E_BAG_ITEM_NO_EXIST;
        }
        barracks.setReadyNum(barracks.getReadyNum() + (goodsInfo.getParamList().get(0).longValue() * count));
        userData.setUpdateOption();
        activity.getLogActivityMgr().addBarracksLog(userId, (goodsInfo.getParamList().get(0).longValue() * count), 1);
        return 0;
    }
}
